// 元素缓慢滑入效果指令

// 参数可通过 binding传入
const distance = 150; // 滑动距离
const duration = 500; // 动画效果时间
const weakMap = new WeakMap(); // 使用 WeakMap 是为了不造成内存泄露
const ob = new IntersectionObserver((entries) => {
  // entries数组 监听到的所有元素,存放相关信息
  for (const entry of entries) {
    if (entry.isIntersecting) {
      // 与视口有交集,开始播放动画
      // entry.target 当前相交元素
      // entry.target.getAnimations(); 可以获取到当前元素绑定的所有的动画，但是基于通用性，可能原先的元素就绑定了动画，就不适用
      const animation = weakMap.get(entry.target);
      if (animation) {
        animation.play();
        ob.unobserve(entry.target); // 播放完成之后就取消观察 不需要再次播放
      }
    }
  }
}); // 监听页面元素

function isBelowViewport(el) {
  const rect = el.getBoundingClientRect();
  return rect.top - distance > window.innerHeight;
}

export default {
  mounted(el, binding) {
    // 当前元素是不是第一个或顶部小于distance
    if (!isBelowViewport(el)) {
      return;
    }
    // js animate
    const animation = el.animate(
      [
        {
          transform: `translateY(${distance}px)`,
          opaciyt: 0.5,
        },
        {
          transform: `translateY(0px)`,
          opaciyt: 1,
        },
      ],
      {
        duration: duration,
        easing: "ease-in-out",
        fill: "forwards",
      }
    );
    animation.pause(); // 最开始的时候暂停 当出现在视口的时候在进行动画
    ob.observe(el); // 每次都监听
    weakMap.set(el, animation); // 将当前的元素和动画绑定在一起
  },
  unmounted(el) {
    ob.unobserve(el); // 卸载时取消监听
  },
};
